package main

import (
	"database/sql"
	"demo_test/modifycollector/DBUtil"
	"demo_test/modifycollector/config"
	"fmt"
	"math/rand"
	"strconv"
	"strings"
	"time"
)

// 模拟采集器demo
// 注意两个 channel 的创建方式
var cfg config.Config

func init() {
	cfg = config.DefaultConfig
}

func main() {
	tick := time.Tick(cfg.Interval)

	in := CreateInsertChannel()
	var conn *sql.DB

	num := GetDataCount(cfg)

	dataChan := CreatDataChannel()

	for {
		select {
		case <-tick:
			GetNewData(cfg, &num, dataChan)
		case t := <-in:
			conn, _ = DBUtil.ConnectMysql(DBUtil.BuildConnection(cfg))
			DBUtil.InsertDB(conn, t)
			conn.Close()
		default:
			fmt.Println("*************")
		}
		time.Sleep(time.Second)
	}
}

// 创建一个插入数据库的channel
func CreateInsertChannel() <-chan map[string]string {
	insertChannel := make(chan map[string]string)
	go func() {
		for {
			insertChannel <- CreateFakeData()
			time.Sleep(10 * time.Second)
		}
	}()
	return insertChannel
}

// 创建一个从channel,从中获取数据,数据从数据库中取出
func CreatDataChannel() chan<- map[string]string {
	dataChannel := make(chan map[string]string)
	go func() {
		for data := range dataChannel {
			fmt.Println(data)
		}
	}()
	return dataChannel
}

func CreateFakeData() map[string]string {
	chars := "abcdefghijklmnopqrstuvwxyz1234567890"
	rand.Seed(time.Now().UnixNano())
	paramLength := 4 + rand.Intn(10)
	var charsNum int
	var param string
	for i := 0; i < paramLength; i++ {
		charsNum = rand.Intn(len(chars))
		param += string(chars[charsNum])
	}
	res := map[string]string{
		"username": param}
	paramLength = 6 + rand.Intn(10)
	param = ""
	for i := 0; i < paramLength; i++ {
		charsNum = rand.Intn(len(chars))
		param += string(chars[charsNum])
	}
	res["pwd"] = param
	return res
}

func GetDataCount(cnf config.Config) int {

	datasourcename := DBUtil.BuildConnection(cnf)
	db, _ := DBUtil.ConnectMysql(datasourcename)
	defer db.Close()

	var build strings.Builder
	build.WriteString("select count(0) from ")
	build.WriteString(cnf.TableName)
	sqlstr := build.String()
	var count int
	if err := db.QueryRow(sqlstr).Scan(&count); err != nil {
		fmt.Errorf(err.Error())
	}

	fmt.Println("********************一开始的数量是×××××××××××××××××××××××××")
	fmt.Println(count)
	fmt.Println("********************第一次查询数量结束×××××××××××××××××××××××××")
	return count
}

func GetNewData(cnf config.Config, beginCount *int, dataChannel chan<- map[string]string) {
	datasourcename := DBUtil.BuildConnection(cnf)
	db, _ := DBUtil.ConnectMysql(datasourcename)
	defer db.Close()

	var build strings.Builder
	build.WriteString("select count(0) from ")
	build.WriteString(cnf.TableName)
	sqlstr := build.String()

	var count int
	if err := db.QueryRow(sqlstr).Scan(&count); err != nil {
		fmt.Errorf(err.Error())
	}

	fmt.Println("********************轮询查询的数量是×××××××××××××××××××××××××")
	fmt.Println(count)
	fmt.Println("********************轮询查询数量结束×××××××××××××××××××××××××")

	if count == *beginCount {
		return
	} else if count > *beginCount {
		num := count - *beginCount
		build.Reset()
		build.WriteString("select ")
		build.WriteString(cnf.Fields)
		build.WriteString(" from ")
		build.WriteString(cnf.TableName)
		build.WriteString(" limit ")
		build.WriteString(strconv.Itoa(*beginCount))
		build.WriteString(",")
		build.WriteString(strconv.Itoa(num))
		sqlstr := build.String()
		*beginCount = count

		rows, _ := DBUtil.GetRows(sqlstr, db)
		defer rows.Close()
		DBUtil.LoadAllData(rows, dataChannel)
	} else {
		fmt.Println("出错了～～～～～～～～～～～～～～～～～")
	}
}
